package mule.model;

//<editor-fold defaultstate="collapsed" desc="Imports">

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.image.Image;
import mule.model.enums.MuleOutfit;

//</editor-fold>

/**
 * The abstract class that has the methods for every subclass to change.
 * 
 * @author stephen
 */
public abstract class Tile 
{
    //<editor-fold defaultstate="collapsed" desc="Properties">

    protected IntegerProperty foodProduction;
    protected IntegerProperty maxFoodProduction;
    protected IntegerProperty energyProduction;
    protected IntegerProperty maxEnergyProduction;
    protected IntegerProperty oreProduction;
    protected IntegerProperty maxOreProduction;
    protected BooleanProperty canPurchase;
    protected StringProperty name;
    protected Mule mule;
    protected Image image;

    //</editor-fold>


    //<editor-fold defaultstate="collapsed" desc="Getters and Setters">

    /**
     * Returns the image property of a particluar tile.
     * 
     * @return a tile's image
     */
    public Image getImage()
    {
        return image;
    }

    /**
     * Gets the image on a tile
     * 
     * @param image that is going to be displayed on the tile to the user
     */
    public void setImage( Image image )
    {
        this.image = image;
    }

    /**
     * Returns the food image that belongs to this tile.
     * 
     * @return The food image to display when drawing the tile
     */
    public Image getFoodImage()
    {
        return null;
    }

    /**
     * Returns the energy image that belongs to this tile.
     * 
     * @return The energy image to display when drawing the tile
     */
    public Image getEnergyImage()
    {
        return null;
    }

    /**
     * Returns the ore image that belongs to this tile.
     * 
     * @return  The ore image to display when drawing the tile
     */
    public Image getOreImage()
    {
        return null;
    }

    /**
     * Gets the food production of a tile
     * 
     * @return The food production of a tile as an IntegerProperty
     */
    public IntegerProperty foodProductionProperty()
    {
        if( foodProduction == null )    
        {
            foodProduction = new SimpleIntegerProperty( 0, "Default" );
        }

        return foodProduction;
    }

    /**
     * Gets the food production of a tile
     * 
     * @return the food production of a tile as a primitive integer
     */
    public int getFoodProduction()
    {
        return foodProductionProperty().get();
    }

    /**
     * Sets food production to a particular amount
     * 
     * @param production amount to set the tile's food production to
     */
    public void setFoodProduction( int production )
    {
        foodProductionProperty().set( production );
    }

    /**
     * Gets the energy production of a tile
     * 
     * @return the energy production that a tile has as an integer property
     */
    public IntegerProperty energyProductionProperty()
    {
        if( energyProduction == null )
        {
            energyProduction = new SimpleIntegerProperty( 0, "Default " );
        }

        return energyProduction;
    }

    /**
     * Gets the energy production of a tile
     * 
     * @return the energy production of a tile as a primitive integer
     */
    public int getEnergyProduction()
    {
        return energyProductionProperty().get();
    }

    /**
     * Sets the energy production on a tile
     * 
     * @param production the amount of energy for the tile to produce
     */
    public void setEnergyProduction( int production )
    {
        energyProductionProperty().set( production );
    }

    /**
     * Gets the ore production of a particular tile
     * 
     * @return the ore production of a tile as an integer property
     */
    public IntegerProperty oreProductionProperty()
    {
        if( oreProduction == null )
        {
            oreProduction = new SimpleIntegerProperty( 0, "Default" );
        }

        return oreProduction;
    }

    /**
     * Gets the ore production of a particular tile
     * 
     * @return the ore production of a tile as a primitive integer 
     */
    public int getOreProduction()
    {
        return oreProductionProperty().get();
    }

    /**
     * Sets the ore production of a tile
     * 
     * @param production the ore production to set for the tile
     */
    public void setOreProduction( int production )
    {
        oreProductionProperty().set( production );
    }

    /**
     * Gets whether or not a tile can be purchased
     * 
     * @return whether or not the property can be bought as a boolean property 
     */
    public BooleanProperty canPurchaseProperty()
    {
        if( canPurchase == null )
        {
            canPurchase = new SimpleBooleanProperty( false, "Default" );
        }

        return canPurchase;
    }

    /**
     * Gets whether or not a tile can be purchased
     * 
     * @return whether or not a tile can be purchased as a primitive boolean
     */
    public boolean canPurchase()
    {
        return canPurchaseProperty().get();
    }

    /**
     * Sets whether or not the tile can be purchased
     * 
     * @param canPurchase whether or not the tile can be purchased
     */
    public void setCanPurchase( boolean canPurchase )
    {
        canPurchaseProperty().set( canPurchase );
    }

    /**
     * Gets the name of the tile
     * 
     * @return the name of the tile as a String property
     */
    public StringProperty nameProperty()
    {
        if( name == null )
        {
            name = new SimpleStringProperty( "None", "Default" );
        }

        return name;
    }

    /**
     * Gets the name of the tile
     * 
     * @return the name of the tile as a primitive String
     */
    public String getName()
    {
        return nameProperty().get();
    }

    /**
     * Sets the name of a tile
     * 
     * @param name the name to set for the tile
     */
    public void setName( String name )
    {
        nameProperty().set( name );
    }

    /**
     * Whether or not the tile has a mule on it.
     * 
     * @return true if the property has a mule, else false 
     */
    public boolean hasMule()
    {
        return mule != null && ( mule.getOutfit() != MuleOutfit.NONE ) ;
    }    
 
    /**
     * Sets whether or not the property has a mule on it
     * 
     * @param m whether or not the tile has a mule on it 
     */
    public void setMule( Mule m )
    {
        mule = m;
    }
    
    /**
     * Gets the outfit that is currently on the mule on the tile
     * 
     * @return outfit that is on the mule on the property
     */
    public MuleOutfit getMuleOutfit()
    {
        return mule.getOutfit();
    }

    //</editor-fold>

    
    //<editor-fold defaultstate="collapsed" desc="Methods">

    /**
     * Turns on food production for the tile and turns off the other productions
     * Also sets the image on the tile to be something else
     */
    public void activateFoodProduction()
    {
        setFoodProduction( maxFoodProduction.get() );
        setOreProduction( 0 );
        setEnergyProduction( 0 );
        setImage( getFoodImage() );
    }

    /**
     * Turns on energy production for the tile and turns off the other productions
     * Also sets the image on the tile to be something else
     */
    public void activateEnergyProduction()
    {
        setEnergyProduction( maxEnergyProduction.get() );
        setOreProduction( 0 );
        setFoodProduction( 0 );
        setImage( getEnergyImage() );
    }

    /**
     * Turns on ore production for the tile and turns off the other production
     * Also sets the image on the tile to be something else
     */
    public void activateOreProduction()
    {
        setOreProduction( maxOreProduction.get() );
        setEnergyProduction( 0 );
        setFoodProduction( 0 );
        setImage( getOreImage() );
    }

    //</editor-fold>
}
